package copy.express;

import copy.application.Process;
import copy.express.pojo.NodeStack;
import copy.express.process.suffix.AbsSuffixExpress;
import copy.meta.impl.ParseEasycopyMetaDataStrategyHandler;
import copy.pojo.IfMeta;
import copy.pojo.MethodMeta;
import copy.pojo.PropertyMeta;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 组件设计原则:
 *          严格禁止 A组件 调用 B组件
 *
 *正确方式:  解开耦合
 *          A组件处理好数据,放到 Application上下文环境类的 成员属性容器中.
 *          B组件从Application上下文环境的 成员属性容器中获取数据.
 *
 */
public class ParseNodeStackStrategy extends AbsSuffixExpress {

    //Class类缓存器
    private static Map<String,Class> classMap = new HashMap<>();

    private static ParseNodeStackStrategy parseNodeStackStrategy ;

    private ParseNodeStackStrategy() {
    }
    public static Process getSingleBean(){
        if (parseNodeStackStrategy == null){
            parseNodeStackStrategy = new ParseNodeStackStrategy();
        }
        return parseNodeStackStrategy;
    }

    /**
     * 控制流程
     * @throws ClassNotFoundException
     */
    @Override
    public void process() throws ClassNotFoundException {
        for (Map<String, MethodMeta> value : ParseEasycopyMetaDataStrategyHandler.interfaceMetaDataMap.values()) {
            for (MethodMeta methodMeta : value.values()) {
                for (PropertyMeta propertyMeta : methodMeta.getPropertyMetas()) {
                    processTargetPropertyName(propertyMeta);
                    processCast(propertyMeta);
                }
            }
        }
    }

    public void processCast(PropertyMeta propertyMeta){
        String cast = propertyMeta.getCast();
        if (cast != null && !cast.equals("") && cast.contains("(")){
            String paramsStr =  cast.substring( cast.indexOf("(")+1,cast.lastIndexOf(")") );
            //生成NodeStack,并保存到Property中
            NodeStack nodeStack = toNodeStack(paramsStr,1);
            propertyMeta.setCastStack(nodeStack);
        }
    }

    public void processTargetPropertyName(PropertyMeta propertyMeta){
        if (propertyMeta.getIfMeta() == null){
            //生成NodeStack,并保存到Property中
            NodeStack nodeStack = toNodeStack(propertyMeta.getResorcePropertyName(),1);
            //中缀表达式转后缀表达式
            toSuffixStack(nodeStack);
            propertyMeta.setNodeStack(nodeStack);
        }else{
            IfMeta ifMeta = propertyMeta.getIfMeta();
            String ifExpression = ifMeta.getIfExpression();
            String[] split = ifExpression.split("\\?");
            //判断部分
            String condition = split[0];  // a > b     a.equals(b)
            NodeStack nodeStack = toNodeStack(condition,2);
            try{
                toSuffixStack(nodeStack);
            }catch (Exception e){
                throw e;
            }

            ifMeta.setConditionNodeStack(nodeStack);
            // 1. 先逻辑运算符拆分 ---> 拆分到多个NodeStack中  2.

            //true的语句
            String[] split2 = split[1].split(":");
            String trueStr = split2[0];
            NodeStack trueStack = toNodeStack(trueStr,1);
            toSuffixStack(trueStack);
            ifMeta.setTrueNodeStack(trueStack);
            //false的语句
            String falseStr = split2[1];
            NodeStack falseStack = toNodeStack(falseStr,1);
            toSuffixStack(falseStack);
            ifMeta.setFalseNodeStack(falseStack);

        }
    }

    @Override
    public NodeStack toNodeStack(String resourceProperty,int model) {
        return new NodeStack(resourceProperty,model);
    }

    public static void main(String[] args) {

        BigDecimal bigDecimal = new BigDecimal(1.1);
        BigDecimal add = bigDecimal.add(new BigDecimal(0.2));
        System.out.println(add.toString());


/*        String a = "1+2";
        System.out.println(a.substring(0,1));
        ParseNodeStackStrategy parseNodeStackStrategy = new ParseNodeStackStrategy();
        NodeStack nodeStack = parseNodeStackStrategy.toNodeStack("a+b*c+(d*e+f)*g");
        Stack<Node> nodes = parseNodeStackStrategy.toSuffixStack(nodeStack);
        for (int i = 0; i < nodes.size(); i++) {
            System.out.print(nodes.get(i).getStringValue()+ "\t" );
        }*/
    }
}
